package com.heima.admin.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.admin.mapper.AdChannelMapper;
import com.heima.admin.mapper.AdSensitiveMapper;
import com.heima.admin.service.WemediaNewsAutoScanService;
import com.heima.aliyun.GreenImageScan;
import com.heima.aliyun.GreenTextScan;
import com.heima.common.constants.wemedia.WemediaConstants;
import com.heima.common.exception.CustomException;
import com.heima.feigns.article.ArticleFeign;
import com.heima.feigns.wemedia.WemediaFeign;
import com.heima.model.admin.pojos.AdChannel;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.common.SensitiveWordUtil;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Slf4j
@Service
public class WemediaNewsAutoScanServiceImpl implements WemediaNewsAutoScanService {

    @Resource
    WemediaFeign wemediaFeign;

    @Value("${file.oss.web-site}")
    String webSite;

    @Resource
    GreenTextScan greenTextScan;

    @Override
    @GlobalTransactional
    public void autoScanByMediaNewsId(Integer wmNewsId) {
        if(wmNewsId==null){
            log.error("当前审核的id为空");
            throw new CustomException(AppHttpCodeEnum.PARAM_INVALID);
        }
        WmNews wmNews = wemediaFeign.findById(wmNewsId);
        if(wmNews==null){
            log.error("审核的自媒体文章不存在，自媒体的id:{}", wmNewsId);
            throw new CustomException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        //判断文章的状态
        if(wmNews.getStatus().equals(WmNews.Status.ADMIN_SUCCESS)&&
                wmNews.getPublishTime().getTime()<=System.currentTimeMillis()){
            publishArticle(wmNews);
            return;
        }
        if(wmNews.getStatus().equals(WmNews.Status.SUCCESS)
                &&wmNews.getPublishTime().getTime()<=System.currentTimeMillis()){
            publishArticle(wmNews);
            return;
        }
        if(wmNews.getStatus().equals(WmNews.Status.SUBMIT)){
           Map<String,Object> contentAndImageResult = handleTextAndImages(wmNews);
            //TODO 4.1 自管理敏感词审核
           boolean isSensitiveScan = handleSensitive((String)contentAndImageResult.get("content"),wmNews);
           if(!isSensitiveScan) return;
            //TODO 4.2 阿里云审核文本内容
            boolean isTextScan = handleTextScan((String) contentAndImageResult.get("content"), wmNews);
            if (!isTextScan) return;
            //TODO 4.3 阿里云图片审核
           boolean isImageScan = handleImageScan((List)contentAndImageResult.get("image"),wmNews);
           if(!isImageScan) return;
            //TODO 4.4 判断文章发布时间大于当前时间，修改状态8
            if(wmNews.getPublishTime().getTime() > System.currentTimeMillis()){
                updateWmNews(wmNews,WmNews.Status.SUCCESS.getCode(),"文章审核通过，待发布");
                return;
            }
            //TODO 5 保存文章相关数据
            publishArticle(wmNews);
            //TODO 6 同步索引库

        }
    }

    @Resource
    private GreenImageScan greenImageScan;

    private boolean handleImageScan(List<String> images, WmNews wmNews) {

        if(images==null||images.size()==0){

            return true;
        }
        boolean flag = true ;
        images = images.stream().distinct().collect(Collectors.toList());
        try {
            Map map = greenImageScan.imageUrlScan(images);
            //审核不通过
            if (map.get("suggestion").equals("block")) {
                updateWmNews(wmNews, (short) 2, "文章图片有违规");
                flag = false;
            }
            //人工审核
            if (map.get("suggestion").equals("review")) {
                updateWmNews(wmNews, (short) 3, "文章图片有不确定元素");
                flag = false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            updateWmNews(wmNews, (short) 3, "阿里云审核失败，转入人工审核");
            flag = false;
        }
        return true;
    }

    private boolean handleTextScan(String content, WmNews wmNews) {
        boolean flag = true ;
        try {
            Map map = greenTextScan.greenTextScan(content);
            if(map.get("suggestion").equals("block")){
                flag=false;
                updateWmNews(wmNews,(short)2,"审核失败，请重新上传！！");
            }
            if(map.get("suggestion").equals("review")){
                flag=false;
                updateWmNews(wmNews,(short)3,"审核失败，建议人工审核");
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("文章审核失败，请转为人工审核，e:{}",e);
            flag=false;
            updateWmNews(wmNews,(short)3,"审核失败，建议人工审核");
        }

        return true;
    }

    @Resource
    AdSensitiveMapper adSensitiveMapper;

    private boolean handleSensitive(String content, WmNews wmNews) {
        boolean flag = true ;
        List<String> allSensitive = adSensitiveMapper.findAllSensitive();
        SensitiveWordUtil.initMap(allSensitive);
        Map<String, Integer> map = SensitiveWordUtil.matchWords(content);
        if(map.size()>0){
            flag = false;
            updateWmNews(wmNews,(short)2,"文章中包含了敏感词:"+map);
        }
        return flag;
    }

    private void updateWmNews(WmNews wmNews, short status, String msg) {
        wmNews.setStatus(status);
        wmNews.setReason(msg);
        ResponseResult responseResult = wemediaFeign.updateWmNews(wmNews);
        if(!responseResult.getCode().equals(0)){
            throw new CustomException(AppHttpCodeEnum.WEMEDIA_UPDATE_ERROR);
        }
    }

    private void publishArticle(WmNews wmNews) {
        ResponseResult responseResult = saveArticle(wmNews);
        if(!responseResult.getCode().equals("0")){
            throw new RuntimeException("文章审核保存app文章失败");
        }
        Object data = responseResult.getData();
        wmNews.setArticleId((long)data);
        updateWmNews(wmNews,(short)9,"文章审核通过");
    }

    @Resource
    AdChannelMapper adChannelMapper;

    @Resource
    ArticleFeign articleFeign;

    private ResponseResult saveArticle(WmNews wmNews) {
        ArticleDto articleDto = new ArticleDto();
        BeanUtils.copyProperties(wmNews,articleDto);
        articleDto.setId(null);
        if(wmNews.getArticleId()!=null){
            articleDto.setId(wmNews.getArticleId());
        }

        if(wmNews.getChannelId()!=null){
            articleDto.setChannelId(wmNews.getChannelId());
            AdChannel adChannel = adChannelMapper.selectById(wmNews.getChannelId());
            if(adChannel!= null){
                articleDto.setChannelName(adChannel.getName());
            }
        }

        WmUser wmUser = wemediaFeign.findWmUserById(wmNews.getUserId());
        if(wmUser==null || wmUser.getStatus().intValue()!=9){
            throw new CustomException(AppHttpCodeEnum.ADMIN_ADUSER_ISNTOEXIT_ERROR);
        }
        if(StringUtils.isNotBlank(wmUser.getName())) {
            articleDto.setAuthorName(wmUser.getName());
        }

        articleDto.setContent(wmNews.getContent());

        return articleFeign.saveArticle(articleDto);
    }


    private Map<String,Object> handleTextAndImages(WmNews wmNews) {
        String content = wmNews.getContent();
        if(StringUtils.isBlank(content)||content.length()>10000){
            return null;
        }
        List<Map> contentList = JSON.parseArray(content, Map.class);
        String contents = contentList.stream()
                .filter(x -> x.get("type").equals("text"))
                .map(y -> y.get("value").toString())
                .collect(Collectors.joining("_hmtt_"));

        contents = wmNews.getTitle()+"_hmtt_"+contents;

        List<String> images = contentList.stream()
                .filter(x -> x.get("type").equals("image"))
                .map(y -> y.get("value").toString())
                .collect(Collectors.toList());
        String imageCover = wmNews.getImages();
        if(StringUtils.isNotBlank(imageCover)){
            images.addAll(
                    Stream.of(imageCover.split(","))
                    .map(x -> webSite+x)
                    .collect(Collectors.toList())
            );
        }

        HashMap<String, Object> resultMap = new HashMap<>();
        resultMap.put("content",contents);
        resultMap.put("images",images);
        return resultMap;
    }


}
